// ----------------
// Project:
// ESA Elevator
// ----------------
//
// Description:
// ----------------
// display_if.v testbench
//
// Version History:
// ----------------
// 140116: adapted visualization process of the display

`timescale 1ns / 1ps

module display_if_tb_public;

  //****************** SIMULATION PARAMETERS *******************//  
  localparam CLK_PERIOD       =  50; // [ns] -> 20 MHz
  localparam NUM_FLOORS       =  99; // number of floors 
  localparam DISPLAY_SEGMENTS =  14;
  //***********************************************************//
  

  //*************** DERIVED SIMULATION PARAMETERS *************// 
  localparam FLOOR_BITS            = min_1(ceil_log2(NUM_FLOORS));
  //***********************************************************//
  

  //********************* MODULE INPUTS ***********************// 
  reg                            CLK;
  reg                            RESET;
  reg [(FLOOR_BITS-1)        :0] CURRENT_FLOOR;
  reg [6                     :0] asciOutHigh;
  reg [6                     :0] asciOutLow;
  //***********************************************************//  


  //********************* MODULE OUTPUTS **********************//
  wire  [(DISPLAY_SEGMENTS-1):0] ENABLE_SEGMENT; 
  //***********************************************************// 
  

  //******************* UUT INSTANTIATION *********************// 
  display_if #(
               .DISPLAY_SEGMENTS (DISPLAY_SEGMENTS),
               .FLOOR_BITS       (FLOOR_BITS))
               
      DISPLAY_IF_i (
                    .CURRENT_FLOOR(CURRENT_FLOOR),
                    .ENABLE_SEGMENT(ENABLE_SEGMENT));                                
  //***********************************************************//
  

  //******************* 20 MHz CLOCK SIGNAL *******************//   
  always begin 
    #(CLK_PERIOD/2) CLK = ~CLK;
  end
  //***********************************************************// 


  //********************* TEST INITIATION *********************//  
  initial begin
    // Initialize Inputs
    CLK                      = 0;
    RESET                    = 1;
    CURRENT_FLOOR            = 0;

    // Wait 125 ns for global reset to finish
    #(3*CLK_PERIOD/2);
    RESET = 0;
    $display("************ STARTING SIMULATION ************");  
    #(5*CLK_PERIOD);
    //--------------------------
    // SELECT FLOORS 
    //--------------------------
    CURRENT_FLOOR    = 0;
    #(CLK_PERIOD);
    CURRENT_FLOOR    = 1;
    #(CLK_PERIOD);
    CURRENT_FLOOR    = 2;
    #(CLK_PERIOD);
    CURRENT_FLOOR    = 3;
    #(CLK_PERIOD);
    CURRENT_FLOOR    = 4;
    #(CLK_PERIOD);
    CURRENT_FLOOR    = 5;
    #(CLK_PERIOD);
    CURRENT_FLOOR    = 6;
    #(CLK_PERIOD);
    CURRENT_FLOOR    = 7;
    #(CLK_PERIOD);
    CURRENT_FLOOR    = 8;
    #(CLK_PERIOD);
    CURRENT_FLOOR    = 9; 
    #(CLK_PERIOD);
    CURRENT_FLOOR    = 10;
    #(CLK_PERIOD);
    CURRENT_FLOOR    = 25;
    #(CLK_PERIOD);
    CURRENT_FLOOR    = 99;  
    #(5*CLK_PERIOD);  
    $display("************ SIMULATION COMPLETE ************");
    $finish;
  end
  //***********************************************************// 


  //****************** VISUALISATION PROCESS ******************//
  always @(ENABLE_SEGMENT) begin
    case (ENABLE_SEGMENT[13:7])
      7'b1111110 : asciOutHigh = 7'h30;
		
      7'b0110000 : asciOutHigh = 7'h31;
		
      7'b1101101 : asciOutHigh = 7'h32;
		
      7'b1111001 : asciOutHigh = 7'h33;
		
      7'b0110011 : asciOutHigh = 7'h34;
		
      7'b1011011 : asciOutHigh = 7'h35;
		
      7'b1011111 : asciOutHigh = 7'h36;
		
      7'b1110000 : asciOutHigh = 7'h37;
		
      7'b1111111 : asciOutHigh = 7'h38;
		
      7'b1111011 : asciOutHigh = 7'h39;
		
      default:     asciOutHigh = 7'h30;		
    endcase

    case (ENABLE_SEGMENT[6:0])
      7'b1111110 : asciOutLow = 7'h30;
		
      7'b0110000 : asciOutLow = 7'h31;
		
      7'b1101101 : asciOutLow = 7'h32;
		
      7'b1111001 : asciOutLow = 7'h33;
		
      7'b0110011 : asciOutLow = 7'h34;
		
      7'b1011011 : asciOutLow = 7'h35;
		
      7'b1011111 : asciOutLow = 7'h36;
		
      7'b1110000 : asciOutLow = 7'h37;
		
      7'b1111111 : asciOutLow = 7'h38;
		
      7'b1111011 : asciOutLow = 7'h39;
		
      default:     asciOutLow = 7'h30;		
    endcase
	end

  always@(asciOutHigh,asciOutLow) begin
    $display("Current floor: %c%c", asciOutHigh,asciOutLow);  
  end 
  //***********************************************************// 
initial begin
  #(100000*CLK_PERIOD)
  $display("************ SIMULATION KILLED BECAUSE OF ERROR ************");
  $finish;
end


  //******************* PARAMETER FUNCTIONS *******************//
  //ceil of the log base 2
  function integer ceil_log2;
    input [31:0] value;
    for (ceil_log2=0; value>0; ceil_log2=ceil_log2+1)
      value = value>>1;
  endfunction
  
  // value cannot be less than 1
  function integer min_1;
    input [31:0] value;
    if (value == 0)
      min_1 = 1;
    else
      min_1 = value;
  endfunction 
  //***********************************************************//      
  
    
endmodule